home *** CD-ROM | disk | FTP | other *** search
/ Cracking 2 / Cracking II..iso / Texty / crackme / riscs-solution.txt < prev    next >
Encoding:
Text File  |  1999-05-31  |  7.8 KB  |  173 lines

  1. R!SC's Solution to Duelist's Crackme #3 -- http://csir.cjb.net -- risc@notme.com :)
  2.  
  3. Difficulty level : 5/10 (probably the toughest crack i have done)
  4.  
  5. Tools Needed : Symantec Resource Workshop 1.0
  6.              : W32Dasm
  7.              : Hex WorkShop
  8.              : Tasm
  9.              : Softice
  10.              : Efnet :) (optional)
  11.              
  12.  
  13. First off (well, after running the crackme, and trying a few random combinations), i loaded
  14. due-cm3.exe into W32Dasm, scrolling through the code, i soon found this bit...
  15.  
  16. the important code...ESI points to button check order array thingy
  17.  
  18. :00401127 0FBE8EFE204000          movsx ecx, byte ptr [esi+004020FE]
  19. :0040112E 83F94D                  cmp ecx, 0000004D    <-- 4D is like a NULL terminator, also used
  20. :00401131 742F                    je 00401162          - for the last bit of maths
  21. :00401133 890D5E214000            mov dword ptr [0040215E], ecx    <-- save the current button iD
  22. :00401139 51                      push ecx            <-- button iD
  23. :0040113A FF7508                  push [ebp+08]        <-- dialog box handle
  24.  
  25. * Reference To: USER32.IsDlgButtonChecked, Ord:0000h
  26.                                   |
  27. :0040113D E8D0010000              Call 00401312
  28. :00401142 46                      inc esi            <-- Counter, points to next button,
  29. :00401143 83F800                  cmp eax, 00000000      - and used in the maths
  30. :00401146 74DF                    je 00401127        <-- Loop until one is found checked...
  31. :00401148 A15E214000              mov eax, dword ptr [0040215E]         <-- Our checked box iD
  32. :0040114D 0FBE8EFE204000          movsx ecx, byte ptr [esi+004020FE] <-- Next button iD
  33. :00401154 0FAFC1                  imul eax, ecx        <-- Multiply next button iD with current one
  34. :00401157 0FAFC6                  imul eax, esi        <-- Multiply count with answer
  35. :0040115A 010562214000            add dword ptr [00402162], eax    <-- Add it to our magic number
  36. :00401160 EBC5                    jmp 00401127
  37.  
  38. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  39. |:00401131(C)
  40. |
  41. :00401162 A162214000              mov eax, dword ptr [00402162]    <-- Our final magic number..
  42. :00401167 6BC04D                  imul eax, 0000004D
  43. :0040116A 3D6654F300              cmp eax, 00F35466        <-- Magic number we have to get...
  44.  
  45.  
  46. So, from this, we know we can bpx IsDlgButtonChecked, to make softice break at the routine
  47. which does the checking. After returning from USER32.IsDlgButtonChecked, if eax is NULL, the
  48. button wasnt checked, and it loops back to get the next iD, if eax != 0, the button is
  49. checked, and it does some maths on it
  50.  
  51. MAGIC NUMBER = MAGIC NUMBER + (Current box iD * Next box iD * Button counter)
  52.  
  53. After the last button, it puts our MAGIC NUMBER into eax, multiplys it by 4D, then compares
  54. it against the predifined number we have to get, F35466.. for the sake of it, to save some 
  55. maths, F35466 / 4D = 328FE (the number i finally use to figure out the correct order of ticks)
  56.  
  57. At the start of the routine, it loads ESI with the check order of the buttons, displaying the
  58. memory at [esi+004020FE] (when ESI==0) we get this information
  59.  
  60. ---button iD check order---
  61.  
  62. 004020FE 16 49 5E 15 27 26 21 25 1D 59 53 37 31 48 5D 0C 61 52 4D
  63.     ESI== 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f 10 11 --
  64.     my id 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18   (9*2)
  65.  
  66. This means bugger all to us, because we dont know which number represents which check box on
  67. the screen. We have to use a resource editor, to look at the dialog box resources, and find out
  68. which box uses which iD..
  69.  
  70. I used Symantec Resource Editor 1.0, availble from http:\\protools.cjb.net (couldnt get BRW to 
  71. load the exe) . So load due-cm3.exe into your resource editor, and click to edit the dialog...
  72. After clicking on each button, starting from the top left, converting the iD into hex, then
  73. writing them down, i got this information from it..
  74.  
  75. Buttons on screen
  76. 61 49 5E 16 25 26 21 59 53    ; top row of check boxes
  77.  
  78. 15 37 31 48 5D 0C 52 27 1D    ; bottom row of check boxes 10-18
  79.  
  80. Okay, with all this information, we know what button gets checked when, and we still cant figure
  81. out the correct order (can you do the maths in your head?)
  82.  
  83. My theory, to write a brute forcer, which will go through every possible combination you can
  84. have, do the maths on them, and compare the result with 328FE (the correct MAGIC NUMBER / 4D)
  85.  
  86. 90 minutes of coding later (i am real bad at this :) i got a result!!
  87.  
  88. Picture this in your head, 18 boxes, can be checked or unchecked, 0 or 1, imagine a binary
  89. value, using 18 bits, to represent these boxes, we test each bit in the binary value, if its
  90. 0 it represents an unchecked box, if its 1, it represents a tick ;) we use a 1 bit binary value,
  91. scrolling this to the left, bit by bit, and increase a counter, so we know which bit we are
  92. checking (bit 0 through to 17), test a with b, if the bit is set, do the maths..
  93.  
  94. (see the comments i added to the source for the brute forcer..)
  95.  
  96. theory behind R!SC's Matrix Brute Forcer (r)
  97.  
  98. we have 18 check boxes, can be either 'checked' or 'unchecked' (1 or 0) 
  99. apparantly, the amount of diff combo's is square of 18, 324???
  100. so where i come up with 262,144 :)
  101.  
  102. we also have a way of testing single 'bits' in a value, by using 'TEST dest, src'
  103. i use a 18bit binary value (well, 32bit binary value, but only use the TEST on the first
  104. 18 bits of it...) (i'll refer to this as my MAGIC NUMBER)
  105.  
  106. i start the MAGIC NUMBER with the first bit set, (01h) then do the maths, check the result,
  107. if it doesnt find the correct answer, we increase the MAGIC NUMBER by 1, and check again....
  108.  
  109. examples of the MAGIC NUMBER, and how it represents the matrix of check boxes....
  110.  
  111. 000000000000000001 = 01h = box 1 checked, 2-18 unckecked, simulate the maths, check the results
  112. 000000000000000010 = 02h = box 2 checked, 1,3-18 unchecked
  113. 000000000000000011 = 03h = box 1,2 checked, 3-18 unckecked
  114. 000000000000000100 = 04h = box 3 checked, 1,2,4-18 unchecked
  115. 000000000000000101
  116. 000000000000000110
  117. 000000000000000111 = 07h = box 1-3 checked, 4-18 unchecked...
  118. 000000000000001000
  119. 000000000000001001
  120.  
  121. 101000110101000110 = 028d46h = box 2,3,7,9,11,12,16,18 checked
  122.                                box 1,4,5,6,8,10,13,14,15,17 unchecked
  123. 111111111111111111 = 03ffffh = box 1-18 checked...
  124.  
  125. to find out if a bit is set or not, i use another 18bit (32bit :) value, with only one bit
  126. set in it (i'll call this X)
  127.  
  128. TEST MAGIC NUMBER, X    ; see if bit 'X' is set in the magic number
  129. JNZ CHECKED                ; if bit 'X' is not '0' jump to calculation routine
  130.  
  131. which will check bit X in the MAGIC NUMBER, and alter the ZERO flag accordingly
  132. i.e, bit X is 0, zero flag is set, bit X is 1, zero flag is cleared...
  133.  
  134. X gets shifted to the left by 1 bit, the counter increased, check the counter, if its equal
  135. to 18, we have checked every bit in the MAGIC NUMBER, and have to loop back to check our result
  136. erm... still with me??
  137.  
  138. examples of X
  139.  
  140. 000000000000000001 = bit 1 set = 01h, counter = 0
  141. 000000000000000010 = bit 2 set = 02h, counter = 1
  142. 000000000000000100 = bit 3 set = 04h, counter = 2
  143. 000000000000001000 = bit 4 set = 08h, counter = 3
  144. 000000000000010000 = bit 5 set = 10h, counter = 4
  145. 000000000000100000 = bit 6 set = 20h, counter = 5
  146. 000000000001000000 = bit 7 set = 40h, counter = 6
  147. ..................
  148. 001000000000000000 = bit 16 set = 08000h, counter = 15
  149. 010000000000000000 = bit 17 set = 10000h, counter = 16
  150. 100000000000000000 = bit 18 set = 20000h, counter = 17
  151. bit gets shifted one more time, counter increased to 18,
  152. counter gets checked, weve done, so loop back and check the answer...
  153.  
  154. okay, go study the source code
  155. ...
  156. ...
  157. heh, you back already? try changing this line
  158.  
  159. :0040116A 3D6654F300              cmp eax, 00F35466     
  160.  
  161. to read 
  162.  
  163. :0040116A 3D6E8BC000              cmp eax, 00C08B6E    ; file offset 76A
  164.  
  165. and figure out the correct sequence :) 
  166.  
  167. (CHANGE ALREADY MADE IN 28026-DUE-CM3.EXE)
  168. (SOLUTION IN TEST.ZIP)
  169.  
  170. R!SC 31st May 1999
  171.  
  172.  
  173.